﻿Public MustInherit Class CommandBase
    Public ReadOnly RequestCode As String
    Public ReadOnly ReplyCode As String

    Public Sub New(ByVal requestCode As String, ByVal replyCode As String)
        Me.RequestCode = requestCode : Me.ReplyCode = replyCode
    End Sub

    Public MustOverride Sub HandleRequest(ByVal envelope As Framework.Net.MessageEnvelope)
    Public MustOverride Sub HandleReply(ByVal envelope As Framework.Net.MessageEnvelope)

    Private Shared mCallbacksEx As New Generic.Dictionary(Of Integer, [Delegate])
    Private Shared mCallbacksExGuiThread As New Generic.Dictionary(Of Integer, Boolean)
    Protected Shared Sub RegisterCallback(ByVal messageId As Integer, ByVal callback As [Delegate], ByVal invokeOnGuiThread As Boolean)
        mCallbacksEx.Add(messageId, callback)
        mCallbacksExGuiThread.Add(messageId, invokeOnGuiThread)
    End Sub
    Protected Shared Sub InvokeCallback(ByVal inReplyToMessageId As Integer, ByVal ParamArray args() As Object)
        If mCallbacksEx.ContainsKey(inReplyToMessageId) Then
            Dim blnFlag As Boolean = mCallbacksExGuiThread(inReplyToMessageId)
            Dim clsCB As [Delegate] = CType(mCallbacksEx(inReplyToMessageId), [Delegate])
            mCallbacksEx.Remove(inReplyToMessageId)
            mCallbacksExGuiThread.Remove(inReplyToMessageId)
            If blnFlag AndAlso Framework.Threading.EventInvokeRequired Then
                If args Is Nothing Then
                    Framework.Threading.MainGuiForm.Invoke(clsCB, inReplyToMessageId)
                ElseIf args.Count = 1 Then
                    Framework.Threading.MainGuiForm.Invoke(clsCB, inReplyToMessageId, args(0))
                ElseIf args.Count = 2 Then
                    Framework.Threading.MainGuiForm.Invoke(clsCB, inReplyToMessageId, args(0), args(1))
                ElseIf args.Count = 3 Then
                    Framework.Threading.MainGuiForm.Invoke(clsCB, inReplyToMessageId, args(0), args(1), args(2))
                ElseIf args.Count = 4 Then
                    Framework.Threading.MainGuiForm.Invoke(clsCB, inReplyToMessageId, args(0), args(1), args(2), args(3))
                Else
                    Throw New NotImplementedException("Support for callbacks with 5 or more arguments not implemented!")
                End If
            Else
                If args Is Nothing Then
                    clsCB.DynamicInvoke(inReplyToMessageId)
                ElseIf args.Count = 1 Then
                    clsCB.DynamicInvoke(inReplyToMessageId, args(0))
                ElseIf args.Count = 2 Then
                    clsCB.DynamicInvoke(inReplyToMessageId, args(0), args(1))
                ElseIf args.Count = 3 Then
                    clsCB.DynamicInvoke(inReplyToMessageId, args(0), args(1), args(2))
                ElseIf args.Count = 4 Then
                    clsCB.DynamicInvoke(inReplyToMessageId, args(0), args(1), args(2), args(3))
                Else
                    Throw New NotImplementedException("Support for callbacks with 5 or more arguments not implemented!")
                End If
            End If
        End If
    End Sub
End Class

Public Class MessageEnvelope
    Public Node As Framework.Net.Node
    Public Message As Framework.Net.MessageBlock

    Friend Sub New(ByVal node As Framework.Net.Node, ByVal message As Framework.Net.MessageBlock)
        Me.Node = node : Me.Message = message
    End Sub
End Class
